package cn.yzgy.yzgyoa.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Set;

/**
 * 缓存助手，用于更新数据时删除缓存，下次查询时重建
 *
 * @author Yqsen
 * @since 2019-10-11 11:11:24
 */
@Slf4j
@Component
public class YzCacheHelper {

    private final StringRedisTemplate stringRedisTemplate;

    public YzCacheHelper(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 删除某个缓存
     *
     * @param cacheName 缓存名，前缀匹配
     */
    private void removeCache(String cacheName) {
        log.debug("清除缓存,KeyPrefix: {}",cacheName);
        Set<String> keys = stringRedisTemplate.keys(cacheName);
        int cleared = 0;
        if (!CollectionUtils.isEmpty(keys)) {
            cleared = keys.size();
            stringRedisTemplate.delete(keys);
            keys.forEach(x -> log.info("-> Key: {} Clear.", x));
        }
        log.debug("缓存Keys: {} 清除完成 清除数量：{}",cacheName,cleared);
    }

    /**
     * 根据操作的返回值判断是否要删除已缓存内容
     *
     * @param res 数据库操作的返回值
     * @param keyName 键名
     * @return 数据库操作的返回值
     */
    public int autoClearCache(int res, String keyName) {
        if (res != 0) {
            removeCache(keyName + "*");
        }
        return res;
    }

    /**
     * 兼容boolean的操作
     *
     * @param res 数据库操作返回值
     * @param keyName 键名
     * @return 数据库操作返回值
     */
    public boolean autoClearCache(boolean res, String keyName) {
        return autoClearCache(res ? 1 : 0, keyName) != 0;
    }

    /**
     * 快速生成键名组合
     *
     * @param args 参数列表
     * @return 组合后，符合规范的参数String
     */
    public String combineArgs(String... args) {
        StringBuilder sb = new StringBuilder("{");
        for (int i = 0; i < args.length; i++) {
            sb.append(args[i]);
            if (i != args.length - 1) {
                sb.append("&");
            }
        }
        return sb.append("}").toString();
    }

}
